--dofile ("libConsole.lua") --/!\ MLS Debug !!!
dofile ("libCollisions.lua")
debug_nb = 0
blanc = Color.new (31, 31, 31)
bleu1 = Color.new (0, 0, 31)
bleu2 = Color.new (0, 0, 15)
-- GigaClass Game --
Game = {}
-- Class Window --
Game.Window = {}
Game.Window.cur = Image.load ("cur.png", VRAM)
Game.Window.win = {}
function Game.Window.new (scr, x1, y1, x2, y2, id)
  Game.Window.win[id] = {
    scr = scr,
    x1 = x1,
    y1 = y1,
    x2 = x2,
    y2 = y2,
    show = true
  }
end
function Game.Window.draw (id)
  if Game.Window.win[id].show then
    screen.drawGradientRect (Game.Window.win[id].scr, Game.Window.win[id].x1, Game.Window.win[id].y1, Game.Window.win[id].x2, Game.Window.win[id].y2, bleu2, bleu1, bleu1, bleu1)
  end
end
function Game.Window.drawText (x, y, text, color, id)
  if Game.Window.win[id].show then
    screen.drawTextBox (Game.Window.win[id].scr, Game.Window.win[id].x1+x, Game.Window.win[id].y1+y, Game.Window.win[id].x2, Game.Window.win[id].y2, text, color)
  end
end
function Game.Window.hideWindow (id)
  Game.Window.win[id].show = false
end
function Game.Window.showWindow (id)
  Game.Window.win[id].show = true
end
-- SubClass Dialog --
Game.Window.Dialog = {}
function Game.Window.Dialog.new (scr, id)
  Game.Window.new (scr, 27, 145, 227, SCREEN_HEIGHT, id)
  a = false
end
function Game.Window.Dialog.draw (scr, texts, color, id)
  Game.Window.draw (id)
  --screen.print (SCREEN_DOWN, 5, 25, table.getn (texts)) -- Debug
  --screen.print (SCREEN_DOWN, 5, 45, tostring (a)) -- Debug
  if not Keys.held.A then
    a = true
  end
  for i=1, table.getn (texts) do
    --screen.print (SCREEN_DOWN, 5+i*6, 5, tostring (i)) -- Debug
    if i == 1 then
      Game.Window.drawText (5, 5, texts[i], color, id)
    elseif i <= 4 then
      Game.Window.drawText (5, 5*i+5*(i-1), texts[i], color, id)
      if i == table.getn (texts) then
        if a and Keys.held.A then
          Game.Window.hideWindow (id)
        end
      end
    elseif i == 5 then
      if Keys.held.A then
        a = false
        table.remove (texts, 1)
        table.remove (texts, 1)
        table.remove (texts, 1)
        table.remove (texts, 1)
        i = 1
      end
    end
  end
end
-- end Dialog --
-- SubClass Choice --
Game.Window.Choice = {}
Game.Window.Choice.choices = {}
function Game.Window.Choice.new (scr, x, y, choices, larg, id)
  local y2 = x+table.getn (choices)*10+10
  Game.Window.new (scr, x, y, x+larg, y2, id)
  choix = 1
end
function Game.Window.Choice.draw (scr, x, y, choices, color, id)
  Game.Window.draw (id)
  local chmax = table.getn (choices)
  for i=1, chmax do
    if i == 1 then
      Game.Window.drawText (12, 5, choices[i], color, id)
    else
      Game.Window.drawText (12, 5*i+5*(i-1), choices[i], color, id)
    end
  end
  if Keys.newPress.Up then
    if choix > 1 then
      choix = choix - 1
    else
      choix = chmax
    end
  elseif Keys.newPress.Down then
    if choix < chmax then
      choix = choix + 1
    else
      choix = 1
    end
  end
  local chx = x+10-Image.width (Game.Window.cur)
  local chy = y+5*choix+5*(choix-1)-1
  if choix~=0 then
    screen.blit (scr, chx, chy, Game.Window.cur)
  end
end
function Game.Window.Choice.isSelected (chsel)
  local retIS = false
  if Keys.newPress.A and choix == chsel then
    retIS = true
  end
  return retIS
end
-- end Choice --
-- end Window --
-- Class Sprite --
Game.Sprite = {}
Game.Sprite.Table = {}
function Game.Sprite.new (image, larg, haut, dest, anims, vitesses, screen, x, y, name, dir)
  local _spR = Sprite.new (image, larg, haut, dest)
  for i=1, table.getn(anims) do
    _spR:addAnimation (anims[i], vitesses[i])
  end
  local x2 = x+larg
  local y2 = y+haut
  Collisions.newObject (name, screen, x, y, x2, y2, "Sprite", _spR)
  Game.Sprite.Table[name] = {}
  Game.Sprite.Table[name].scr = screen
  Game.Sprite.Table[name].x = x
  Game.Sprite.Table[name].y = y
  Game.Sprite.Table[name].x2 = x2
  Game.Sprite.Table[name].y2 = y2
  Game.Sprite.Table[name].dir = dir
  Game.Sprite.Table[name].spr = _spR
end
function Game.Sprite.draw (name)
  Collisions.update (name, Game.Sprite.Table[name].x, Game.Sprite.Table[name].y, Game.Sprite.Table[name].x2, Game.Sprite.Table[name].y2)
  Game.Sprite.Table[name].spr:playAnimation(Game.Sprite.Table[name].scr, Game.Sprite.Table[name].x, Game.Sprite.Table[name].y, Game.Sprite.Table[name].dir)
end
function Game.Sprite.moveLeft (name, nbpix)
  Game.Sprite.Table[name].x = Game.Sprite.Table[name].x-nbpix
  Game.Sprite.Table[name].x2 = Game.Sprite.Table[name].x2-nbpix
  Game.Sprite.Table[name].dir = 4
end
function Game.Sprite.moveRight (name, nbpix)
  Game.Sprite.Table[name].x = Game.Sprite.Table[name].x+nbpix
  Game.Sprite.Table[name].x2 = Game.Sprite.Table[name].x2+nbpix
  Game.Sprite.Table[name].dir = 2
end
function Game.Sprite.moveUp (name, nbpix)
  Game.Sprite.Table[name].y = Game.Sprite.Table[name].y-nbpix
  Game.Sprite.Table[name].y2 = Game.Sprite.Table[name].y2-nbpix
  Game.Sprite.Table[name].dir = 1
end
function Game.Sprite.moveDown (name, nbpix)
  Game.Sprite.Table[name].y = Game.Sprite.Table[name].y+nbpix
  Game.Sprite.Table[name].y2 = Game.Sprite.Table[name].y2+nbpix
  Game.Sprite.Table[name].dir = 3
end
-- end Sprite --
-- Class Platform --
Game.Platform = {}
Game.Platform.Table = {}
function Game.Platform.initPlatform (screen, x, y)
  Game.Platform.scr = screen
  Game.Platform.x = x
  Game.Platform.y = y
end
function Game.Platform.newHero (x, y, w, h, dest, vit, img)
  local anims = {
  {0, 1, 2, 1},
  {3, 4, 5, 4},
  {6, 7, 8, 7},
  {9, 10, 11, 10}}
  local vitesses = {vit, vit, vit, vit}
  Game.Platform.Table["_hero_"] = {}
  Game.Platform.Table["_hero_"].isJumping = false
  Game.Platform.Table["_hero_"].width = w
  Game.Platform.Table["_hero_"].height = h
  --player.y = 230
  --player.x = 50
  Game.Platform.Table["_hero_"].jumpspeed = 10
  Game.Sprite.new (img, w, h, dest, anims, vitesses, Game.Platform.scr, x, y-1, "_hero_", 2)
  Game.Platform.Table["_hero_"].gravity = y
  Game.Platform.Table["_hero_"].yfix = y
end
function Game.Platform.drawHero ()
  Game.Sprite.draw ("_hero_")
end
function Game.Platform.initHeroCommands (px)
  gmax = Game.Platform.Table["_hero_"].yfix
  dt_co = CO["_hero_"].inCollisionWith
  if not Collisions.isInCollision ("_hero_") then
    gmax = Game.Platform.Table["_hero_"].yfix
    d_co = "Not in collision"
    --Console.print ("not in collision", 1)
  else
    d_co = tostring (CO[Collisions.nameObject ("_hero_")].y)
    --Console.print ("in collision", 2)
  end
  if Keys.held.Right and not Game.Platform.Table["_hero_"].isJumping then
    Game.Sprite.moveRight ("_hero_", px)
    --Console.print ("moveRight on floor", 3)
  elseif Keys.held.Left and not Game.Platform.Table["_hero_"].isJumping then
    Game.Sprite.moveLeft ("_hero_", px)
    --Console.print ("moveLeft on floor", 4)
  elseif Keys.held.Right and Game.Platform.Table["_hero_"].isJumping then
    Game.Sprite.Table["_hero_"].x = Game.Sprite.Table["_hero_"].x+px
    Game.Sprite.Table["_hero_"].x2 = Game.Sprite.Table["_hero_"].x2+px
    Game.Sprite.Table["_hero_"].dir = 1
    --Console.print ("moveRight in Jump", 5)
  elseif Keys.held.Left and Game.Platform.Table["_hero_"].isJumping then
    Game.Sprite.Table["_hero_"].x = Game.Sprite.Table["_hero_"].x-px
    Game.Sprite.Table["_hero_"].x2 = Game.Sprite.Table["_hero_"].x2-px
    Game.Sprite.Table["_hero_"].dir = 3
    --Console.print ("moveLeft in Jump", 6)
  end
  if Keys.newPress.A and not Game.Platform.Table["_hero_"].isJumping then
    Game.Platform.Table["_hero_"].isJumping = true
    --Game.Sprite.Table["_hero_"].dir = Game.Sprite.Table["_hero_"].dir-1
    --Console.print ("Jump", 7)
  end
  if Collisions.mode ("_hero_") == "down" then
    gmax = CO[Collisions.nameObject ("_hero_")].y-Game.Platform.Table["_hero_"].height
    d_co = tostring (CO[Collisions.nameObject ("_hero_")].y)
    Game.Platform.Table["_hero_"].jumpspeed = 10
    Game.Platform.Table["_hero_"].isJumping = false
    gmax = CO[Collisions.nameObject ("_hero_")].y-Game.Platform.Table["_hero_"].height
    Game.Platform.Table["_hero_"].gravity = gmax
    --Console.print ("Collision down", 8)
  end
  if Game.Platform.Table["_hero_"].isJumping then
    Game.Platform.Table["_hero_"].jumpspeed = Game.Platform.Table["_hero_"].jumpspeed - 0.5
    Game.Platform.Table["_hero_"].gravity = Game.Platform.Table["_hero_"].gravity - Game.Platform.Table["_hero_"].jumpspeed
    --Console.print ("isJumping", 9)
  end
  if Game.Platform.Table["_hero_"].gravity == gmax then
    Game.Platform.Table["_hero_"].jumpspeed = 10
    Game.Platform.Table["_hero_"].isJumping = false
    --Console.print ("gravity == gmax", 10)
  end
  if Game.Platform.Table["_hero_"].gravity > gmax then
    Game.Platform.Table["_hero_"].gravity = gmax
    --Console.print ("gravity > gmax", 11)
  end
  Game.Sprite.Table["_hero_"].y = Game.Platform.Table["_hero_"].gravity
  Game.Sprite.Table["_hero_"].y2 = Game.Sprite.Table["_hero_"].y+Game.Platform.Table["_hero_"].height
end
function Game.Platform.reInitPositions ()
  Game.Platform.Table["_hero_"].gravity = 100
  Game.Platform.Table["_hero_"].jumpspeed = 10
  Game.Platform.Table["_hero_"].isJumping = false
end
function Game.Platform.debug ()
  screen.print (SCREEN_DOWN, 0, 0, "Is in collision = "..d_co)
  screen.print (SCREEN_DOWN, 0, 10, "Gravity = "..tostring (Game.Platform.Table["_hero_"].gravity))
  screen.print (SCREEN_DOWN, 0, 20, "Is jumping = "..tostring (Game.Platform.Table["_hero_"].isJumping))
  screen.print (SCREEN_DOWN, 0, 30, "Jumpspeed = "..tostring (Game.Platform.Table["_hero_"].jumpspeed))
  screen.print (SCREEN_DOWN, 0, 40, "Yfix = "..tostring (Game.Platform.Table["_hero_"].yfix))
  screen.print (SCREEN_DOWN, 0, 50, "Gmax = "..tostring (gmax))
  screen.print (SCREEN_DOWN, 0, 60, "Hero X = "..tostring (Game.Sprite.Table["_hero_"].x))
  screen.print (SCREEN_DOWN, 0, 70, "Hero X2 = "..tostring (Game.Sprite.Table["_hero_"].x2))
  screen.print (SCREEN_DOWN, 0, 80, "Hero Y = "..tostring (Game.Sprite.Table["_hero_"].y))
  screen.print (SCREEN_DOWN, 0, 90, "Hero Y2 = "..tostring (Game.Sprite.Table["_hero_"].y2))
  screen.print (SCREEN_DOWN, 0, 100, "In collision with = "..tostring (dt_co))
  screen.print (SCREEN_DOWN, 0, 110, "Collision Mode = "..tostring (Collisions.mode ("_hero_")))
  function Game.Platform.debugRects (name)
    screen.drawRect (SCREEN_UP, CO[name].x, CO[name].y, CO[name].x2, CO[name].y2, blanc)
  end
end
function Game.Platform.newBlock (x, y, img, name)
  local x2 = x+Image.width (img)
  local y2 = y+Image.height (img)
  Collisions.newObject (name, Game.Platform.scr, Game.Platform.x+x, Game.Platform.y+y, Game.Platform.x+x2, Game.Platform.y+y2, "Image")
  Game.Platform.Table[name] = {}
  Game.Platform.Table[name].x = Game.Platform.x+x
  Game.Platform.Table[name].y = Game.Platform.y+y
  Game.Platform.Table[name].x2 = Game.Platform.x+x2
  Game.Platform.Table[name].y2 = Game.Platform.y+y2
  Game.Platform.Table[name].img = img
end
function Game.Platform.drawBlock (name, passable)
  Collisions.initCollision ("_hero_", name)
  Collisions.update (name, Game.Platform.Table[name].x, Game.Platform.Table[name].y, Game.Platform.Table[name].x2, Game.Platform.Table[name].y2)
  Collisions.drawObject (name, Game.Platform.Table[name].img)
  if not passable then
    if Keys.held.Right and Collisions.mode ("_hero_") == "right" then
      Game.Sprite.moveLeft ("_hero_", 2)
      Game.Sprite.moveRight ("_hero_", 1)
      --Console.print ("collision hero right", 12)
    elseif Keys.held.Left and Collisions.mode ("_hero_") == "left" then
      Game.Sprite.moveRight ("_hero_", 2)
      Game.Sprite.moveLeft ("_hero_", 1)
      --Console.print ("collision hero left", 13)
    end
  end
end
-- end Platform --
function Game.clearMemory ()
  blanc, bleu1, bleu2, gmax, d_co, dt_co, Game.Window.cur, Game.Window.a, Game.Window.win, Game.Window.new, Game.Window.draw, Game.Window.drawText, Game.Window.hideWindow, Game.Window.showWindow, Game.Window.Dialog.new, Game.Window.Dialog.draw, a, Game.Window.Choice.choices, Game.Window.Choice.new, choix, Game.Window.Choice.draw, Game.Sprite.Table, Game.Sprite.new, Game.Sprite.draw, Game.Sprite.moveLeft, Game.Sprite.moveRight, Game.Sprite.moveUp, Game.Sprite.moveDown, Game.Platform.Table, Game.Platform.newBlock, Game.Platform.drawBlock, Game.clearMemory, Game.Window.Dialog, Game.Window.Choice, Game.Window, Game.Sprite, Game.Platform, Game = nil
  Collisions = nil
  CO = nil
  collectgarbage ()
end
-- end Game --